﻿/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */
#include "theme.h"
#include "ui_theme.h"
#include "radioproxystyle.h"

#include <QGSettings>
#include <QDebug>
#include <QtDBus/QDBusConnection>
#include <QtConcurrent>
#include <QRadioButton>

#include "widgets/Label/iconlabel.h"

#include "cursor/xcursortheme.h"
#include "../../../shell/customstyle.h"
#include "../../../shell/utils/utils.h"

// GTK主题
#define THEME_GTK_SCHEMA "org.mate.interface"
#define MODE_GTK_KEY     "gtk-theme"
#define ICON_GTK_KEY     "icon-theme"

#define BG_MATE_SCHEMA   "org.mate.background"
#define BG_FILE_KEY      "picture-filename"

// QT主题
#define THEME_QT_SCHEMA  "org.ukui.style"
#define MODE_QT_KEY      "style-name"
#define THEME_TRAN_KEY   "menu-transparency"
#define PEONY_TRAN_KEY   "peony-side-bar-transparency"
#define ICON_QT_KEY      "icon-theme-name"
#define WIDGET_QT_KEY    "widget-theme-name"
#define COLOR_QT_KEY     "theme-color"

#define GLOBAL_SCHEMA    "org.ukui.globaltheme.settings"
#define GLOBAL_NAME_KEY  "global-theme-name"
#define ISMODIFY_KEY     "is-modified"

#define ICONTHEMEPATH       "/usr/share/icons/"
#define SYSTHEMEPATH        "/usr/share/themes/"
#define CURSORS_THEMES_PATH "/usr/share/icons/"

#define CURSOR_THEME_SCHEMA "org.ukui.peripherals-mouse"
#define CURSOR_THEME_KEY    "cursor-theme"

// 透明度设置
#define PERSONALSIE_SCHEMA        "org.ukui.control-center.personalise"
#define PERSONALSIE_TRAN_KEY      "transparency"
#define PERSONALSIE_BLURRY_KEY    "blurry"
#define PERSONALSIE_EFFECT_KEY    "effect"
#define PERSONALSIE_SAVE_TRAN_KEY "save-transparency"

const QString kDefCursor =           "DMZ-White";
const QString UbuntuVesionEnhance =  "22.04";
const QString kXder =                "XRender";

const int transparency = 85;
//保存关闭特效模式之前的透明度
int save_trans = 0;

const QStringList effectList {"blur", "kwin4_effect_translucency", "kwin4_effect_maximize", "zoom"};
const QStringList kIconsList {"computer.png", "user-trash.png", "system-file-manager.png", "ukui-control-center.png", "kylin-software-center.png", "kylin-video.png", "kylin-assistant.png"};
const QStringList kIntelIconList {"computer.png", "kylin-software-center.png", "ukui-control-center.png", "kylin-weather.png", "calendar-app.png", "kylin-camera.png"};

const QStringList defaultIconList {"kylin-startmenu.png", "kylin-software-center.png", "indicator-china-weather.png", "burner.png", "kylin-music.png", "kylin-photo-viewer.png"};
const QStringList heyinIconList {"kylin-alarm-clock.png", "kylin-clipboard.png", "ukui-control-center.png", "kylin-calendar.png", "kylin-ipmsg.png", "kylin-photo-viewer.png"};
const QStringList classicIconList {"kylin-startmenu.png", "kylin-software-center.png", "kylin-alarm-clock.png", "indicator-china-weather.png", "yhkylin-backup-tools.png", "kylin-clipboard.png"};
namespace {

    // Preview cursors
    const char * const cursor_names[] =
    {
        "bd_double_arrow",
        "dnd-none",
        "left_ptr",
        "hand2",
        "watch",
        "crosshair",
    };

    const int numCursors = 6;     // The number of cursors from the above list to be previewed
}

Theme::Theme()
{
    ui = new Ui::Theme;
    pluginWidget = new QWidget;
    pluginWidget->setAttribute(Qt::WA_DeleteOnClose);

    pluginName = tr("Theme");
    pluginType = PERSONALIZED;
    ui->setupUi(pluginWidget);

    initThemeUi();
    setupGSettings();

    // 设置组件
    setupComponent();
    setupSettings();
    initThemeMode();
    initIconTheme();
    initCursorTheme();
    initConnection();
    initSearchText();
    hideIntelComponent();
}

Theme::~Theme()
{
    delete ui;
    ui = nullptr;
}

QString Theme::plugini18nName() {
    return pluginName;
}

int Theme::pluginTypes() {
    return pluginType;
}

QWidget *Theme::pluginUi() {
    return pluginWidget;
}

const QString Theme::name() const {

    return QStringLiteral("Theme");
}

bool Theme::isShowOnHomePage() const
{
    return true;
}

QIcon Theme::icon() const
{
    return QIcon::fromTheme("ukui-note-color-symbolic");
}

bool Theme::isEnable() const
{
    return true;
}

void Theme::initThemeUi()
{
    mThemeModeFrame = new QFrame(pluginWidget);
    mThemeModeFrame->setFixedHeight(156);
    mThemeModeFrame->setFrameShape(QFrame::Shape::Box);

    QHBoxLayout *hLyt = new QHBoxLayout(mThemeModeFrame);
    mThemeModeLabel = new TitleLabel(mThemeModeFrame);

    mLightBtn = new ThemeButton(tr("Light"), QPixmap(QString("://img/plugins/theme/%1.png").arg("light")), mThemeModeFrame);
    mDarkBtn = new ThemeButton(tr("Dark"),QPixmap(QString("://img/plugins/theme/%1.png").arg("dark")), mThemeModeFrame);
    mDefaultBtn = new ThemeButton(Utils::isTablet() ? tr("Auto") : tr("Default"), QPixmap(QString("://img/plugins/theme/%1.png").arg("default")),mThemeModeFrame);

    mThemeModeBtnGroup = new QButtonGroup(this);
    mThemeModeBtnGroup->addButton(mDefaultBtn);
    mThemeModeBtnGroup->addButton(mDarkBtn);
    mThemeModeBtnGroup->addButton(mLightBtn);

    buildThemeModeBtn(mLightBtn);
    buildThemeModeBtn(mDarkBtn);
    buildThemeModeBtn(mDefaultBtn);

    hLyt->setSpacing(40);
    hLyt->setContentsMargins(16, 0 , 0, 0);
    hLyt->addWidget(mLightBtn);
    hLyt->addWidget(mDarkBtn);
    hLyt->addWidget(mDefaultBtn);
    hLyt->addStretch();

    ui->thememodeLayout->addWidget(mThemeModeLabel);
    ui->thememodeLayout->addSpacing(8);
    ui->thememodeLayout->addWidget(mThemeModeFrame);
}

void Theme::initSearchText() {
    //~ contents_path /Theme/Window Theme
    mThemeModeLabel->setText(tr("Window Theme"));
    //~ contents_path /Theme/Icon theme
    mThemeIconLabel->setText(tr("Icon theme"));
    if (mThemeCursorLabel) {
        //~ contents_path /Theme/Cursor theme
        mThemeCursorLabel->setText(tr("Cursor theme"));
    }
    //~ contents_path /Theme/Performance mode
    ui->perforLabel->setText(tr("Performance mode"));
    //~ contents_path /Theme/Transparency
    ui->transparencyLabel->setText(tr("Transparency"));
}

void Theme::setupSettings() {
    QString filename = QDir::homePath() + "/.config/ukui-kwinrc";
    kwinSettings = new QSettings(filename, QSettings::IniFormat, this);

    QStringList keys = kwinSettings->childGroups();
    kwinSettings->beginGroup("Plugins");
    bool kwin = kwinSettings->value("blurEnabled", kwin).toBool();

    if (!kwinSettings->childKeys().contains("blurEnabled") || isBlurEffect()) {
        kwin = true;
    } else {
        kwin = false;
    }

    kwinSettings->endGroup();

    effectSwitchBtn->setChecked(kwin);

    if (effectSwitchBtn->isChecked()) {
        ui->transFrame->setVisible(true);
        ui->line->setVisible(true);
    } else {
        ui->transFrame->setVisible(false);
        ui->line->setVisible(false);
    }

    if (keys.contains("Compositing")) {
        kwinSettings->beginGroup("Compositing");
        QString xder;
        bool kwinOG = false;
        bool kwinEN = true;
        xder = kwinSettings->value("Backend", xder).toString();
        kwinOG = kwinSettings->value("OpenGLIsUnsafe", kwinOG).toBool();
        kwinEN = kwinSettings->value("Enabled", kwinEN).toBool();
        if (xder == kXder || kwinOG || !kwinEN) {
            ui->frame_4->setVisible(false);
            ui->verticalSpacer_2->changeSize(0, 0);
            ui->effectLabel->setVisible(false);
            personliseGsettings->set(PERSONALSIE_EFFECT_KEY, false);
        } else {
            ui->lowLabel->setPixmap(QPixmap("://img/plugins/theme/opacity-currency.svg"));
            ui->highlabel->setPixmap(QPixmap("://img/plugins/theme/opaque-light.svg"));
        }
        kwinSettings->endGroup();
    } else {
        ui->lowLabel->setPixmap(QPixmap("://img/plugins/theme/opacity-currency.svg"));
        ui->highlabel->setPixmap(QPixmap("://img/plugins/theme/opaque-light.svg"));
    }
}

void Theme::setupComponent() {

    mDarkBtn->setVisible(!Utils::isCommunity());

    mDefaultBtn->setProperty("value", "ukui-default");
    mLightBtn->setProperty("value", "ukui-light");
    mDarkBtn->setProperty("value", "ukui-dark");

    ui->tranSlider->setRange(35, 100);

    ui->tranSlider->setValue(static_cast<int>(personliseGsettings->get(PERSONALSIE_TRAN_KEY).toDouble() * 100.0));
    connect(ui->tranSlider, &QSlider::valueChanged, this, [=]() {
        changeTranpancySlot(ui->tranSlider->value());
    });

    //构建并填充特效开关按钮
    effectSwitchBtn = new KSwitchButton(pluginWidget);
    ui->effectHorLayout->addWidget(effectSwitchBtn);

    ui->kwinFrame->setVisible(false);
    ui->transFrame->setVisible(true);
    ui->line->setVisible(true);

    initGlobalTheme();
    initControlTheme();
#if SP2
    initJumpTheme();
#endif
}

void Theme::buildThemeModeBtn(ThemeButton *button)
{
    connect(mThemeModeBtnGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), [=](QAbstractButton * eBtn){
        emit button->mBtnCheckedSignals(eBtn == button ? true : false);
    });

}

void Theme::initThemeMode() {
    // 获取当前主题
    QString currentThemeMode = qtSettings->get(MODE_QT_KEY).toString();
    if ("ukui-white" == currentThemeMode || "ukui-default" == currentThemeMode) {
        mThemeModeBtnGroup->buttonClicked(mDefaultBtn);
        emit mDefaultBtn->clicked();
    } else if ("ukui-dark" == currentThemeMode || "ukui-black" == currentThemeMode){
        mThemeModeBtnGroup->buttonClicked(mDarkBtn);
        emit mDarkBtn->clicked();
    } else {
        mThemeModeBtnGroup->buttonClicked(mLightBtn);
        emit mLightBtn->clicked();
    }

    qApp->setStyle(new InternalStyle("ukui"));

    // 监听主题改变
    connect(qtSettings, &QGSettings::changed, this, [=](const QString &key) {
        QString currentThemeMode = qtSettings->get(key).toString();
        if (key == "styleName") {
            // 获取当前主题
            for (QAbstractButton * button : mThemeModeBtnGroup->buttons()){
                QVariant valueVariant = button->property("value");
                if ("ukui-black" == currentThemeMode) {
                    currentThemeMode = "ukui-dark";
                } else if("ukui-white" == currentThemeMode) {
                    currentThemeMode = "ukui-default";
                }
                if (valueVariant.isValid() && valueVariant.toString() == currentThemeMode) {
                    disconnect(mThemeModeBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(themeBtnClickSlot(QAbstractButton*)));
                    button->click();
                    connect(mThemeModeBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(themeBtnClickSlot(QAbstractButton*)));
                }
            }
            qApp->setStyle(new InternalStyle("ukui"));
        }
        if (key == "iconThemeName") {
            QString icoName = qtSettings->get(ICON_QT_KEY).toString();
            foreach (QAbstractButton *btn, mThemeIconBtnGroup->buttons()) {
                if (btn->property("value").isValid() && btn->property("value") == icoName) {
                    disconnect(mThemeIconBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(iconThemeBtnClickSlot(QAbstractButton*)));
                    btn->click();
                    connect(mThemeIconBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(iconThemeBtnClickSlot(QAbstractButton*)));
                }
            }
        }

        if (key == "themeColor") {
            updateAccentColorSlot(currentThemeMode);
        }
    });

    connect(gtkSettings,&QGSettings::changed,this,[=] (const QString &key) {
       if(key == "iconTheme") {
           QString icoName = qtSettings->get(ICON_QT_KEY).toString();
           foreach (QAbstractButton *btn, mThemeIconBtnGroup->buttons()) {
               if (btn->property("value").isValid() && btn->property("value") == icoName) {
                   disconnect(mThemeIconBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(iconThemeBtnClickSlot(QAbstractButton*)));
                   btn->click();
                   connect(mThemeIconBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(iconThemeBtnClickSlot(QAbstractButton*)));
               }
           }
       }
    });

    connect(curSettings,&QGSettings::changed,this,[=](const QString &key) {
       if(key == "cursorTheme") {
            QString cursorTheme = curSettings->get(CURSOR_THEME_KEY).toString();
            foreach (QAbstractButton *btn, mThemeCursorBtnGroup->buttons()) {
                if (btn->property("value").isValid() && btn->property("value") == cursorTheme) {
                    disconnect(mThemeCursorBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(cursorThemeBtnClickSlot(QAbstractButton*)));
                    btn->click();
                    connect(mThemeCursorBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(cursorThemeBtnClickSlot(QAbstractButton*)));
                }
            }
       }
    });

    connect(personliseGsettings, &QGSettings::changed,this,[=] (const QString &key) {
       if (key == "effect") {
           qApp->setStyle(new InternalStyle("ukui"));
           bool effectEnabled = personliseGsettings->get("effect").toBool();
           effectSwitchBtn->setChecked(effectEnabled);
       }
    });

    connect(mThemeModeBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(themeBtnClickSlot(QAbstractButton*)));
}

void Theme::initIconTheme() {
    mThemeIconFrame = new QFrame(pluginWidget);
    mThemeIconFrame->setMinimumHeight(156);
    mThemeIconFrame->setFrameShape(QFrame::Shape::Box);

    FlowLayout *fLyt = new FlowLayout(mThemeIconFrame, 16, 40, 16);
    mThemeIconLabel = new TitleLabel(mThemeIconFrame);


    // 构建图标主题Widget Group，方便更新选中/非选中状态
    mThemeIconBtnGroup = new QButtonGroup;

    //构建图标主题QDir
    QDir themesDir = QDir(ICONTHEMEPATH);
    QStringList IconThemeList = themesDir.entryList(QDir::Dirs);
    foreach (QString themedir, IconThemeList) {
        if (("ukui-icon-theme-default" == themedir) || ("ukui-hp" == themedir)) {
            initIconThemeWidget(themedir, fLyt);
            break;
        }
    }
    foreach (QString themedir, IconThemeList) {
        if ((Utils::isCommunity() && (!themedir.compare("ukui") || !themedir.compare("ukui-classical") || !themedir.compare("ukui-fashion"))) ||
            (!Utils::isCommunity() && themedir.startsWith("ukui-icon-theme-")) ||
            (Utils::isTablet() && (!themedir.compare("ukui") || themedir.startsWith("ukui-classical")))) {

            if (("ukui-icon-theme-basic" == themedir)  || ("ukui-icon-theme-default" == themedir) || ("ukui-hp" == themedir)) {
                  continue;
            }
            initIconThemeWidget(themedir, fLyt);
        }
    }

    connect(mThemeIconBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(iconThemeBtnClickSlot(QAbstractButton*)));

    ui->iconverLyt->addWidget(mThemeIconLabel);
    ui->iconverLyt->addWidget(mThemeIconFrame);
    ui->iconverLyt->addSpacing(40);
}

void Theme::initControlTheme()
{
    if (!qtSettings->keys().contains("themeColor")) {
        return;
    }

    QString colorName = qtSettings->get(COLOR_QT_KEY).toString();

    mControlMap.insert("daybreakBlue", QColor(55, 144, 250));
    mControlMap.insert("jamPurple",    QColor(114, 46, 209));
    mControlMap.insert("magenta",      QColor(235, 48, 150));
    mControlMap.insert("sunRed",       QColor(243, 34, 45));
    mControlMap.insert("sunsetOrange", QColor(246, 140, 39));
    mControlMap.insert("dustGold",     QColor(255, 217, 102));
    mControlMap.insert("polarGreen",   QColor(82, 196, 41));

    mControlLabel = new TitleLabel();
    mControlLabel->setMaximumWidth(100);
    mControlLabel->setText(tr("Corlor"));

    mControlHLyt = new QHBoxLayout();
    mControlHLyt->addWidget(mControlLabel);
    mControlHLyt->addSpacing(32);

    mControlFrame = new QFrame(pluginWidget);
    mControlFrame->setMinimumHeight(60);
    mControlFrame->setFrameShape(QFrame::Shape::Box);

    QMap<QString, QColor>::const_iterator it = mControlMap.constBegin();
    while (it != mControlMap.constEnd()) {

        QRadioButton *radioBtn = new QRadioButton(mControlFrame);
        mRadioBtnList.append(radioBtn);
        radioBtn->setToolTip(dullTranslation(it.key()));
        radioBtn->setProperty("key", it.key());
        RadioProxystyle *style = new RadioProxystyle(it.value());
        radioBtn->setStyle(style);

        if (!colorName.compare(radioBtn->property("key").toString())) {
            radioBtn->setChecked(true);
        }

        mControlHLyt->addWidget(radioBtn);

        connect(radioBtn, &QRadioButton::clicked, this, [=] {
            const QString& value = radioBtn->property("key").toString();
            qtSettings->set(COLOR_QT_KEY, value);
            revokeGlobalThemeSlot("getQtAccentRole", value);
        });
        it++;
    }

    mControlHLyt->addStretch();
    mControlFrame->setLayout(mControlHLyt);
    ui->controlLyt->addWidget(mControlFrame);
}

void Theme::initCursorTheme(){
    if (Utils::isTablet())
        return;
    mThemeCursorFrame = new QFrame(pluginWidget);
    mThemeCursorFrame->setMinimumHeight(156);
    mThemeCursorFrame->setFrameShape(QFrame::Shape::Box);

    FlowLayout *fLyt = new FlowLayout(mThemeCursorFrame, 16, 40, 16);

    mThemeCursorLabel = new TitleLabel(mThemeCursorFrame);

    QStringList cursorThemes = getSystemCursorThemes();

    mThemeCursorBtnGroup = new QButtonGroup(this);

    for (QString cursor : cursorThemes){
        if (cursor == "dark-sense") {
            initCursorThemeWidget(cursor , fLyt);
        }
     }
    for (QString cursor : cursorThemes){
        if (cursor != "dark-sense") {
            initCursorThemeWidget(cursor , fLyt);
        }
    }

    connect(mThemeCursorBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(cursorThemeBtnClickSlot(QAbstractButton*)));

    ui->cursorVerLayout->addWidget(mThemeCursorLabel);
    ui->cursorVerLayout->addWidget(mThemeCursorFrame);
    // To fix  129277
    mThemeCursorLabel->setVisible(false);
    mThemeCursorFrame->setVisible(false);
//    ui->cursorVerLayout->addSpacing(40);
}

void Theme::initGlobalTheme()
{
    if (mGlobalSettings == nullptr) {
        return;
    }
    const QString globalName = mGlobalSettings->get("global-theme-name").toString();

    mSwitchFrame = new QFrame(pluginWidget);
    mSwitchFrame->setMinimumHeight(196);
    mSwitchFrame->setFrameShape(QFrame::Shape::Box);

    mFLyt = new FlowLayout(mSwitchFrame, 16, 40, 16);
    mSwitchLabel = new TitleLabel();
    mSwitchLabel->setText(tr("Theme"));

    ui->switchLyt->addWidget(mSwitchLabel);
    mGlobalthemehelper = GlobalThemeHelper::getInstance();

    mThemeBtnGroup = new QButtonGroup(this);

    for (GlobalTheme *theme: mGlobalthemehelper->getAllGlobalThemes()) {
        mGlobalthemehelper->loadThumbnail(theme);

        QString themeName = theme->getThemeName();
        QString i18nName  = theme->getLocaleThemeName();

        ThemeButton *btn = new ThemeButton(i18nName, mSwitchFrame);
        btn->setProperty("value", themeName);
        btn->setRect(QSize(200, 164));
        mThemeBtnGroup->addButton(btn);

        mGlobalMap.insert(i18nName, btn);

        if (globalName == themeName) {
            mPrePicUnit = btn;
            btn->setBtnClicked(true);
            mThemeBtnGroup->buttonClicked(btn);
        }

        if (!themeName.compare("custom")) {
            mCustomPicUnit = btn;
        }

        mFLyt->addWidget(btn);

        connect(theme, &GlobalTheme::thumbnailLoaded, this, [=]{
            btn->setPixmap(theme->getThumbnail());
        });
    }
    ui->switchLyt->addWidget(mSwitchFrame);
    ui->switchLyt->addSpacing(40);
    connect(mThemeBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(changeGlobalThemeSlot(QAbstractButton*)));
}

void Theme::initJumpTheme()
{
    mJumpLabel = new TitleLabel();
    mJumpLabel->setText(tr("Other"));

    QVBoxLayout *aboutVLyt = new QVBoxLayout();
    aboutVLyt->setContentsMargins(0, 0, 0, 0);

    QPushButton *wallBtn = new QPushButton(tr("Set"));
    wallBtn->setFixedSize(QSize(96, 36));
    mWallHLyt = new QHBoxLayout();
    mWallHLyt->setContentsMargins(16, 0, 16, 0);
    mWallHLyt->addWidget(new QLabel(tr("Wallpaper")));
    mWallHLyt->addWidget(wallBtn);

    mOtherFrame = new QFrame();
    mOtherFrame->setMinimumHeight(120);
    mOtherFrame->setFrameShape(QFrame::Shape::Box);
    mOtherFrame->setLayout(aboutVLyt);

    QPushButton *soundBtn = new QPushButton(tr("Set"));
    soundBtn->setFixedSize(QSize(96, 36));
    mSoundHLyt = new QHBoxLayout();
    mSoundHLyt->setContentsMargins(16, 0, 16, 0);
    mSoundHLyt->addWidget(new QLabel(tr("Beep")));
    mSoundHLyt->addWidget(soundBtn);

    aboutVLyt->addLayout(mWallHLyt);
    aboutVLyt->addWidget(setLine(mOtherFrame));
    aboutVLyt->addLayout(mSoundHLyt);

    ui->jumpLyt->addWidget(mJumpLabel);
    ui->jumpLyt->addWidget(mOtherFrame);

    connect(wallBtn, &QPushButton::clicked, this, [=]{
        jumpFunctionSlot("wallpaper");
    });

    connect(soundBtn, &QPushButton::clicked, this, [=]{
        jumpFunctionSlot("audio");
    });
}

void Theme::initConnection()
{
    connect(ui->resetBtn, &QPushButton::clicked, this, &Theme::resetBtnClickSlot);
    connect(effectSwitchBtn, &KSwitchButton::stateChanged, [this](bool checked) {
        changeEffectSlot(checked);
    });
    connect(mMateBgSettings, &QGSettings::changed, this, [=](const QString &key) {
        if (key == "pictureFilename") {
            const QString& value = mMateBgSettings->get(key).toString();
            mGlobalthemehelper->updateCustomThemeSetting("getWallPaperPath", value);
        }
    });
}

void Theme::initIconThemeWidget(QString themedir , FlowLayout *horLyt)
{
    // 获取当前图标主题(以QT为准，后续可以对比GTK两个值)
    QString currentIconTheme = qtSettings->get(ICON_QT_KEY).toString();

    QDir appsDir = QDir(ICONTHEMEPATH + themedir + "/32x32/apps/");
    QDir placesDir = QDir(ICONTHEMEPATH + themedir + "/32x32/places/");
    QDir devicesDir = QDir(ICONTHEMEPATH + themedir + "/32x32/devices/");
    appsDir.setFilter(QDir::Files | QDir::NoSymLinks);
    devicesDir.setFilter(QDir::Files | QDir::NoSymLinks);
    placesDir.setFilter(QDir::Files | QDir::NoSymLinks);

    QStringList showIconsList;
    QStringList realIconsList;

    if (!Utils::isTablet()) {
        if (("ukui-icon-theme-default" == themedir)) {
            realIconsList = defaultIconList;
        } else if (("ukui-icon-theme-fashion" == themedir)) {
            realIconsList = heyinIconList;
        } else if (("ukui-icon-theme-classical" == themedir)) {
            realIconsList = classicIconList;
        } else {
            return;
        }
    } else {
        realIconsList = kIntelIconList;
    }

    for (int i = 0; i < realIconsList.size(); i++) {
        if (QFile(appsDir.path() + "/" + realIconsList.at(i)).exists()) {
            showIconsList.append(appsDir.path() + "/" + realIconsList.at(i));
        } else if (QFile(devicesDir.path() + "/" + realIconsList.at(i)).exists()) {
            showIconsList.append(devicesDir.path() + "/" + realIconsList.at(i));
        } else if (QFile(placesDir.path() + "/" + realIconsList.at(i)).exists()) {
            showIconsList.append(placesDir.path() + "/" + realIconsList.at(i));
        }
    }
    ThemeButton *button = new ThemeButton(dullTranslation(themedir.section("-", -1, -1, QString::SectionSkipEmpty)), showIconsList, pluginWidget);
    button->setProperty("value", themedir);
     mThemeIconBtnGroup->addButton(button);
    connect(mThemeIconBtnGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), [=](QAbstractButton * eBtn){
        emit button->mBtnCheckedSignals(eBtn == button ? true : false);
    });
    // 加入Layout
    horLyt->addWidget(button);

    if (themedir == currentIconTheme){
        button->clicked();
        mThemeIconBtnGroup->buttonClicked(button);
    }
}

void Theme::initCursorThemeWidget(QString themedir, FlowLayout *fLyt)
{
    // 获取当前指针主题
    QString currentCursorTheme;
    currentCursorTheme = curSettings->get(CURSOR_THEME_KEY).toString();

    QList<QPixmap> cursorVec;
    QString path = CURSORS_THEMES_PATH + themedir;
    XCursorTheme *cursorTheme = new XCursorTheme(path);

    for(int i = 0; i < numCursors; i++){
        int size = qApp->devicePixelRatio() * 8;
        QImage image = cursorTheme->loadImage(cursor_names[i],size);
        cursorVec.append(QPixmap::fromImage(image));
    }

    ThemeButton *button = new ThemeButton(dullCursorTranslation(themedir), cursorVec, pluginWidget);
    button->setProperty("value", themedir);
     mThemeCursorBtnGroup->addButton(button);
    connect(mThemeCursorBtnGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), [=](QAbstractButton * eBtn){
        emit button->mBtnCheckedSignals(eBtn == button ? true : false);
    });
    // 加入Layout
    fLyt->addWidget(button);

    if (themedir == currentCursorTheme){
        button->clicked();
        mThemeCursorBtnGroup->buttonClicked(button);
    }
}

QStringList Theme::getSystemCursorThemes() {
    QStringList themes;
    QDir themesDir(CURSORS_THEMES_PATH);

    if (themesDir.exists()){
        foreach (QString dirname, themesDir.entryList(QDir::Dirs)){
            if (dirname == "." || dirname == "..")
                continue;
            QDir themeDir(CURSORS_THEMES_PATH + dirname + "/cursors/");
            if (themeDir.exists())
                themes.append(dirname);
        }
    }
    return themes;
}

QFrame *Theme::setLine(QFrame *frame)
{
    QFrame *line = new QFrame(frame);
    line->setMinimumSize(QSize(0, 1));
    line->setMaximumSize(QSize(16777215, 1));
    line->setLineWidth(0);
    line->setFrameShape(QFrame::HLine);
    line->setFrameShadow(QFrame::Sunken);
    return line;
}

QStringList Theme::readFile(QString filepath) {
    QStringList fileCont;
    QFile file(filepath);
    if (file.exists()) {
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            qWarning() << "ReadFile() failed to open" << filepath;
            return QStringList();
        }
        QTextStream textStream(&file);
        while (!textStream.atEnd()) {
            QString line= textStream.readLine();
            line.remove('\n');
            fileCont<<line;
        }
        file.close();
        return fileCont;
    } else {
        qWarning() << filepath << " not found"<<endl;
        return QStringList();
    }
}

void Theme::setupGSettings() {
    const QByteArray id(THEME_GTK_SCHEMA);
    const QByteArray idd(THEME_QT_SCHEMA);
    const QByteArray iid(CURSOR_THEME_SCHEMA);
    const QByteArray iiid(PERSONALSIE_SCHEMA);
    const QByteArray globalID(GLOBAL_SCHEMA);
    const QByteArray bgID(BG_MATE_SCHEMA);
    gtkSettings         = new QGSettings(id,   QByteArray(), this);
    qtSettings          = new QGSettings(idd,  QByteArray(), this);
    curSettings         = new QGSettings(iid,  QByteArray(), this);
    personliseGsettings = new QGSettings(iiid, QByteArray(), this);
    mMateBgSettings     = new QGSettings(bgID, QByteArray(), this);

    if (QGSettings::isSchemaInstalled(globalID)) {
        mGlobalSettings = new QGSettings(globalID, QByteArray(), this);
    }
}

void Theme::kwinCursorSlot(QString value) {

    QString filename = QDir::homePath() + "/.config/kcminputrc";
    QSettings *mouseSettings = new QSettings(filename, QSettings::IniFormat);

    mouseSettings->beginGroup("Mouse");
    mouseSettings->setValue("cursorTheme", value);
    mouseSettings->endGroup();

    delete mouseSettings;
    mouseSettings = nullptr;

    QDBusMessage message = QDBusMessage::createSignal("/KGlobalSettings", "org.kde.KGlobalSettings", "notifyChange");
    QList<QVariant> args;
    args.append(5);
    args.append(0);
    message.setArguments(args);
    QDBusConnection::sessionBus().send(message);
}

QString Theme::dullCursorTranslation(QString str) {
    if (!QString::compare(str, "blue-crystal")){
        return tr("Blue-Crystal");
    } else if (!QString::compare(str, "lightseeking")) {
        return tr("Light-Seeking");
    } else if (!QString::compare(str, "DMZ-Black")) {
        return tr("DMZ-Black");
    } else if (!QString::compare(str, "DMZ-White")) {
        return tr("DMZ-White");
    } else if (!QString::compare(str, "dark-sense")) {
        return tr("Dark-Sense");
    } else {
        return str;
    }
}

QString Theme::getCursorName() {
    return curSettings->get(CURSOR_THEME_KEY).toString();
}

QString Theme::getGlobalName()
{
    mGlobalName = mGlobalSettings->get(GLOBAL_NAME_KEY).toString();
    return mGlobalName;
}

void Theme::hideIntelComponent()
{
    ui->resetBtn->setVisible(false);
    if (Utils::isTablet()) {
        ui->transFrame->setVisible(false);
        ui->line->setVisible(false);
    }
}

bool Theme::isBlurEffect()
{
    QDBusInterface ifc("org.kde.KWin",
                        "/Effects",
                        "org.kde.kwin.Effects",
                        QDBusConnection::sessionBus());
    QStringList effects = ifc.property("activeEffects").toStringList();
    return effects.contains("blur");
}

QString Theme::dullTranslation(QString str) {
    if (!QString::compare(str, "basic")){
        return tr("basic");
    } else if (!QString::compare(str, "classical")) { // 启典
        return Utils::isTablet() ? tr("classic") : tr("Classic");
    } else if (!QString::compare(str, "default") || !QString::compare(str, "xunguang")) { // 寻光
        return Utils::isTablet() ? tr("basic") : tr("Light-Seeking");
    } else if (!QString::compare(str, "fashion") || !QString::compare(str, "heyin")) {   // 和印
        return tr("HeYin");
    } else if (!QString::compare(str, "hp")) {
        return tr("hp");
    } else if (!QString::compare(str, "ukui")) {
        return tr("ukui");
    } else if (!QString::compare(str, "daybreakBlue")) {
        return tr("daybreakBlue");
    } else if (!QString::compare(str, "jamPurple")) {
        return tr("jamPurple");
    } else if (!QString::compare(str, "magenta")) {
        return tr("magenta");
    } else if (!QString::compare(str, "sunRed")) {
        return tr("sunRed");
    } else if (!QString::compare(str, "sunsetOrange")) {
        return tr("sunsetOrange");
    } else if (!QString::compare(str, "dustGold")) {
        return tr("dustGold");
    } else if (!QString::compare(str, "polarGreen")) {
        return tr("polarGreen");
    } else {
        return tr("default");
    }
}

// 重置设置
void Theme::resetBtnClickSlot() {

    emit mThemeModeBtnGroup->buttonClicked(mDefaultBtn);

    curSettings->reset(CURSOR_THEME_KEY);
    QString cursorTheme = kDefCursor;
    QString defaultCursor = getCursorName();
    if (defaultCursor.isEmpty()) {
        curSettings->set(CURSOR_THEME_KEY, kDefCursor);
    } else {
        cursorTheme = defaultCursor;
    }
    kwinCursorSlot(cursorTheme);

    qtSettings->reset(ICON_QT_KEY);
    gtkSettings->reset(ICON_GTK_KEY);

    if (ui->effectFrame->isVisible()) {
        effectSwitchBtn->setChecked(true);
        qtSettings->reset(THEME_TRAN_KEY);
        qtSettings->reset(PEONY_TRAN_KEY);
        personliseGsettings->reset(PERSONALSIE_TRAN_KEY);
        ui->tranSlider->setValue(transparency);
    }
}

void Theme::writeKwinSettings(bool change, QString theme, bool effect) {
    Q_UNUSED(theme);
    Q_UNUSED(effect);

    if (!change) {
        kwinSettings->beginGroup("Plugins");
        kwinSettings->setValue("blurEnabled", false);
        kwinSettings->setValue("kwin4_effect_maximizeEnabled", false);
        kwinSettings->setValue("kwin4_effect_translucencyEnabled", false);
        kwinSettings->endGroup();
#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0)

#else
        for (int i = 0; i < effectList.length(); i++) {
            QDBusMessage message = QDBusMessage::createMethodCall("org.kde.KWin",
                                                       "/Effects",
                                                       "org.ukui.kde.Effects",
                                                       "unloadEffect");
            message << effectList.at(i);
            QDBusConnection::sessionBus().send(message);
        }
#endif
    } else {
        kwinSettings->beginGroup("Plugins");
        kwinSettings->setValue("blurEnabled", true);
        kwinSettings->setValue("kwin4_effect_maximizeEnabled", true);
        kwinSettings->setValue("kwin4_effect_translucencyEnabled", true);
        kwinSettings->endGroup();
#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0)

#else
        // 开启模糊特效：
        for (int i = 0; i < effectList.length(); i++) {

            QDBusMessage message = QDBusMessage::createMethodCall("org.kde.KWin",
                                                                  "/Effects",
                                                                  "org.kde.kwin.Effects",
                                                                  "loadEffect");
            message << effectList.at(i);
            QDBusConnection::sessionBus().send(message);
        }
#endif

    }
    kwinSettings->sync();
}

void Theme::themeBtnClickSlot(QAbstractButton *button) {
    // 设置主题
     QString themeMode = button->property("value").toString();
     QString currentThemeMode = qtSettings->get(MODE_QT_KEY).toString();

     if (QString::compare(currentThemeMode, themeMode)){
         QString tmpMode;
         if ("ukui-dark" == themeMode) {
             tmpMode = "ukui-black";

             revokeGlobalThemeSlot("getDefaultLightDarkMode", "dark");
             revokeGlobalThemeSlot("getQtDarkThemeName", themeMode);
             revokeGlobalThemeSlot("getGtkDarkThemeName", tmpMode);
         } else {
             tmpMode = "ukui-white";
             revokeGlobalThemeSlot("getDefaultLightDarkMode", "light");
             revokeGlobalThemeSlot("getQtLightThemeName", themeMode);
             revokeGlobalThemeSlot("getGtkLightThemeName", tmpMode);
         }
         gtkSettings->set(MODE_GTK_KEY, tmpMode);
         qtSettings->set(MODE_QT_KEY, themeMode);
     }
}

void Theme::changeGlobalThemeSlot(QAbstractButton *button)
{
    QVariant value = button->property("value");
    GlobalTheme *theme = nullptr;
    for (GlobalTheme *globaltheme: mGlobalthemehelper->getAllGlobalThemes()) {
        if (globaltheme->getThemeName() == value)
            theme = globaltheme;
    }
    if (!theme) return;

    if (mPrePicUnit != nullptr) mPrePicUnit->setBtnClicked(false);

    mPrePicUnit = static_cast<ThemeButton *>(button);

    bool supportBlur  = theme->getSupportBlur();
    bool blurEnable   = theme->getBlurEnabled();

    bool supportTranspancy = theme->getSupportTransparency();
    int transparency = theme->getTransparencyBlur();

    QString globalName = theme->getThemeName();
    QString wallpaper  = theme->getWallPaperPath();
    QString iconName   = theme->getIconThemeName();
    QString cursorName = theme->getCursorThemeName();
    QString widgetName = theme->getWidgetStyleName();
    QString colorTheme = theme->getDefaultLightDarkMode();
    QString accentColor= theme->getQtAccentRole();
    QString gtkColorTheme;

    if (!colorTheme.compare("light")) {
        colorTheme = theme->getQtLightThemeName();
        gtkColorTheme = theme->getGtkLightThemeName();
    } else if (!colorTheme.compare("dark")) {
        colorTheme = theme->getQtDarkThemeName();
        gtkColorTheme = theme->getGtkDarkThemeName();
    }

    mMateBgSettings->set(BG_FILE_KEY, wallpaper);

    mGlobalSettings->set(GLOBAL_NAME_KEY, globalName);
    mGlobalSettings->set(ISMODIFY_KEY, false);

    qtSettings->set(ICON_QT_KEY, iconName);
    qtSettings->set(WIDGET_QT_KEY, widgetName);
    qtSettings->set(MODE_QT_KEY, colorTheme);
    qtSettings->set(COLOR_QT_KEY, accentColor);

    gtkSettings->set(ICON_GTK_KEY, iconName);
    gtkSettings->set(MODE_GTK_KEY, gtkColorTheme);

    curSettings->set(CURSOR_THEME_KEY, cursorName);

    if (supportBlur) {
        changeEffectBtnSlot(supportBlur);
    }

    if (supportTranspancy) {
        changeTranpancySliderSlot(transparency);
    }
}

void Theme::revokeGlobalThemeSlot(const QString &funcName, const QString &value)
{
#ifdef SP2
    if (mGlobalSettings) {
        mGlobalSettings->set(ISMODIFY_KEY, true);
        mGlobalSettings->set(GLOBAL_NAME_KEY, "custom");
    }
    if (mCustomPicUnit && !mCustomPicUnit->isChecked()) {
        disconnect(mThemeBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(changeGlobalThemeSlot(QAbstractButton*)));
        mCustomPicUnit->setBtnClicked(true);
        mThemeBtnGroup->buttonClicked(mCustomPicUnit);
        connect(mThemeBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(changeGlobalThemeSlot(QAbstractButton*)));
    }

    if (mPrePicUnit != mCustomPicUnit) {
        mPrePicUnit->setBtnClicked(false);
        mPrePicUnit = mCustomPicUnit;
    }
    mGlobalthemehelper->updateCustomThemeSetting(funcName, value);
#endif
}

void Theme::changeGlobalDirSlot()
{
    GlobalThemeHelper *globalHelper = GlobalThemeHelper::getInstance();
    QMap<QString, GlobalTheme*> actGlobal;
    const QStringList &mapKeys = mGlobalMap.keys();
    for (GlobalTheme *theme: globalHelper->getAllGlobalThemes()) {
        globalHelper->loadThumbnail(theme);
        actGlobal.insert(theme->getLocaleThemeName(), theme);
    }

    QTimer::singleShot(500, this, [=]{
        if (actGlobal.keys().length() > mapKeys.length()) {
            for (QString themeName : actGlobal.keys()) {
                if (!mapKeys.contains(themeName)) {
                    ThemeButton *btn = new ThemeButton(themeName, actGlobal[themeName]->getThumbnail(), mSwitchFrame);
                    QString property = actGlobal[themeName]->getThemeName();
                    btn->setProperty("value", property);
                    btn->setRect(QSize(200, 164));
                    mThemeBtnGroup->addButton(btn);
                    mFLyt->addWidget(btn);
                    mGlobalMap.insert(themeName, btn);
                }
            }
        } else {
            for (QString themeName : mapKeys) {
                if (!actGlobal.keys().contains(themeName)) {
                    ThemeButton *gloablBtn = mGlobalMap[themeName];
                    if (gloablBtn->property("value") == getGlobalName()) {
                        mCustomPicUnit->setBtnClicked(true);
                        mThemeBtnGroup->buttonClicked(mCustomPicUnit);
                    }
                    mThemeBtnGroup->removeButton(gloablBtn);
                    mGlobalMap.remove(themeName);
                    delete gloablBtn;
                }
            }
        }
    });

}

void Theme::changeEffectSlot(bool checked)
{
    if (!checked) {
        save_trans = static_cast<int>(personliseGsettings->get(PERSONALSIE_TRAN_KEY).toDouble() * 100.0);
        personliseGsettings->set(PERSONALSIE_SAVE_TRAN_KEY, save_trans);
        personliseGsettings->set(PERSONALSIE_TRAN_KEY, 1.0);
        qtSettings->set(THEME_TRAN_KEY, 100);
        qtSettings->set(PEONY_TRAN_KEY, 100);
        ui->tranSlider->setValue(100);
    } else {
        save_trans = personliseGsettings->get(PERSONALSIE_SAVE_TRAN_KEY).toInt();
        ui->tranSlider->setValue(save_trans);
    }
    // 提供给外部监听特效接口
    personliseGsettings->set(PERSONALSIE_EFFECT_KEY, checked);
    QString currentThemeMode = qtSettings->get(MODE_QT_KEY).toString();
    ui->transFrame->setVisible(checked && !Utils::isTablet());
    ui->line->setVisible(checked && !Utils::isTablet());
    writeKwinSettings(checked, currentThemeMode, true);
}

void Theme::changeEffectBtnSlot(bool checked)
{
    effectSwitchBtn->setChecked(checked);
}

void Theme::changeTranpancySlot(int value)
{
    personliseGsettings->set(PERSONALSIE_TRAN_KEY,(static_cast<int>(value) / 100.0));
    qtSettings->set(THEME_TRAN_KEY, value);
    qtSettings->set(PEONY_TRAN_KEY, value);
}

void Theme::changeTranpancySliderSlot(int value)
{
    ui->tranSlider->setValue(value);
}

void Theme::jumpFunctionSlot(const QString &arg)
{
    QProcess::startDetached("ukui-control-center", QStringList() << "-m" << arg);
}

void Theme::iconThemeBtnClickSlot(QAbstractButton *button)
{
    // 设置图标主题
    QVariant valueVariant = button->property("value");
    qtSettings->set(ICON_QT_KEY, valueVariant);
    gtkSettings->set(ICON_GTK_KEY, valueVariant);

    revokeGlobalThemeSlot("getIconThemeName", valueVariant.toString());
}

void Theme::cursorThemeBtnClickSlot(QAbstractButton *button)
{
    // 设置光标主题
    QVariant valueVariant = button->property("value");
    curSettings->set(CURSOR_THEME_KEY, valueVariant);
    kwinCursorSlot(valueVariant.toString());
    revokeGlobalThemeSlot("getCursorThemeName", valueVariant.toString());
}

void Theme::updateAccentColorSlot(const QString &color)
{
    for (QRadioButton *btn : mRadioBtnList) {
        if (btn->property("key") == color) {
            btn->blockSignals(true);
            btn->setChecked(true);
            btn->blockSignals(false);
        }
    }
}

double Theme::convertToTran(const int value) {
    switch (value) {
    case 1:
        return 0.2;
        break;
    case 2:
        return 0.4;
        break;
    case 3:
        return 0.6;
        break;
    case 4:
        return 0.8;
        break;
    case 5:
        return 1.0;
        break;
    default:
        return 1.0;
        break;
    }
}

int Theme::tranConvertToSlider(const double value) {
    if (0.2 ==  value) {
        return 1;
    } else if (0.4 ==  value) {
        return 2;
    } else if (0.6 ==  value) {
        return 3;
    } else if (0.8 ==  value) {
        return 4;
    } else if (1.0 ==  value) {
        return 5;
    } else {
        return 5;
    }
}
